package br.requisiteworks.requisito.modelo.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.modelo.Projeto;
import br.requisiteworks.requisito.modelo.Relacionamento;
import br.requisiteworks.requisito.modelo.Requisito;
import br.requisiteworks.requisito.modelo.dao.RelacionamentoDao;
import br.requisiteworks.util.persistencia.ResultadoVazio;

@Repository
public class JpaRelacionamentoDao implements RelacionamentoDao {

	@PersistenceContext
	private EntityManager em;

	@Override
	public List<Relacionamento> select(Projeto projeto) throws ResultadoVazio {
		TypedQuery<Relacionamento> query = em.createQuery(
				"SELECT r FROM Relacionamento r WHERE r.projeto=:projeto",
				Relacionamento.class);

		query.setParameter("projeto", projeto);

		List<Relacionamento> result = query.getResultList();

		ResultadoVazio.verificaVazio(result);

		return result;
	}

	@Override
	public Relacionamento select(Requisito a, Requisito b)
			throws ResultadoVazio {
		TypedQuery<Relacionamento> query = em
				.createQuery(
						"SELECT r FROM Relacionamento r WHERE (r.a=:a AND r.b=:b) OR (r.a=:b AND r.b=:a)",
						Relacionamento.class);

		query.setParameter("a", a);
		query.setParameter("b", b);
		Relacionamento result = null;
		try {
			result = query.getSingleResult();
		} catch (NoResultException nre) {
			throw new ResultadoVazio();
		}
		ResultadoVazio.verificaVazio(result);

		return result;
	}

	@Override
	public List<Relacionamento> selectRelacionamentos(Requisito requisito)
			throws ResultadoVazio {
		TypedQuery<Relacionamento> query = em
				.createQuery(
						"SELECT r FROM Relacionamento r WHERE r.a=:requisito OR r.b=:requisito",
						Relacionamento.class);

		query.setParameter("requisito", requisito);

		List<Relacionamento> result = query.getResultList();

		ResultadoVazio.verificaVazio(result);

		return result;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(Relacionamento relacionamento) {
		em.remove(relacionamento);
		em.flush();
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void insert(Relacionamento relacionamento) {
		em.persist(relacionamento);
		em.flush();

	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void update(Relacionamento relacionamento) {
		em.merge(relacionamento);
		em.flush();
	}

}
